﻿using System;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows.Media;

namespace RealTimeStocks
{
	class StockParameters : INotifyPropertyChanged
	{
		public ValueWithBackground DiffPrc
		{
			get
			{
				if (CurrentValue.NumberValue == null || BuyAmount == 0)
					return null;
				var obj = new ValueWithBackground();
				if (IsSumRow)
					obj.NumberValue = ((CurrentValue.NumberValue / BuyAmount) - 1) * 100;
				else
				{
					if (BuyValue != 0)
						obj.NumberValue = ((CurrentValue.NumberValue / BuyValue) - 1) * 100;
					else
						obj.NumberValue = 0;
				}
				if (obj.NumberValue > 0)
					obj.ForeColor = new SolidColorBrush(Colors.Green);
				else
					obj.ForeColor = new SolidColorBrush(Colors.Red);
				return obj;
			}
		}

		public ValueWithBackground DiffSellPrc
		{
			get
			{
				if (CurrentValue.NumberValue == null || IsSumRow || SellAmount == 0)
					return null;
				var obj = new ValueWithBackground();
				if (SellValue != 0)
					obj.NumberValue = ((CurrentValue.NumberValue / SellValue) - 1) * 100;
				else
					obj.NumberValue = 0;

				if (obj.NumberValue < 0)
					obj.ForeColor = new SolidColorBrush(Colors.Green);
				else
					obj.ForeColor = new SolidColorBrush(Colors.Red);
				return obj;
			}
		}

		private int _volume;
		public int Volume
		{
			get { return _volume; }
			set
			{
				_volume = value;
				NotifyPropertyChanged("Volume");
			}
		}

		public string StockName { get; set; }
		public bool IsSumRow { get; set; }

		public decimal _buyValue = 0;
		public decimal BuyValue
		{
			get { return _buyValue; }
			set
			{
				_buyValue = value;
				NotifyPropertyChanged("CurrentProfit");
				NotifyPropertyChanged("BuyAmount");
			}
		}

		public decimal _sellValue = 0;
		public decimal SellValue
		{
			get { return _sellValue; }
			set
			{
				_sellValue = value;
				NotifyPropertyChanged("CurrentProfit");
				NotifyPropertyChanged("SellAmount");
			}
		}

		public decimal? Expenses
		{
			get
			{
				decimal minCommission = 1.47M;
				decimal commission = 0.003M;
				decimal stockmarket = 0.00025M;
				decimal transfer = 0.0006M;
				decimal SettlementExpenses = 0.5M;
				decimal tax = 0.002M;
				if (BuyPieces == 0 || CurrentValue == null || !CurrentValue.NumberValue.HasValue)
					return null;
				decimal a = (Math.Max(minCommission, BuyPieces * CurrentValue.NumberValue.Value * commission)
					+ BuyPieces * CurrentValue.NumberValue.Value * (stockmarket + transfer + tax)) * 2
					+ SettlementExpenses;
				return Math.Round(a, 2);
			}
		}

		private decimal _buyAmount = 0;
		public decimal BuyAmount
		{
			get
			{
				if (IsSumRow)
					return _buyAmount;
				return Math.Round(BuyValue * BuyPieces, 2);
			}
			set
			{
				_buyAmount = value;
				NotifyPropertyChanged("BuyAmount");
			}
		}

		public decimal _sellAmount = 0;
		public decimal SellAmount
		{
			get
			{
				if (IsSumRow)
					return _sellAmount;
				return SellPieces * SellValue;
			}
			set
			{
				_sellAmount = value;
				NotifyPropertyChanged("SellAmount");
			}
		}

		public decimal _currentAmount = 0;
		public decimal CurrentAmount
		{
			get
			{
				if (IsSumRow)
					return _currentAmount;
				if (CurrentValue.NumberValue.HasValue)
					return CurrentValue.NumberValue.Value * (BuyPieces - SellPieces);
				else
					return 0;
			}
			set
			{
				_currentAmount = value;
				NotifyPropertyChanged("CurrentAmount");
			}
		}

		private ValueWithBackground _currentProfit;
		public ValueWithBackground CurrentProfit
		{
			get
			{
				if (IsSumRow)
					return _currentProfit;
				ValueWithBackground obj = new ValueWithBackground();
				if (BuyAmount > 0 && CurrentAmount > 0)
				{
					obj.NumberValue = CurrentAmount - BuyAmount - ((Expenses.HasValue && BuyPieces > 0) ? Expenses.Value : 0);
					if (obj.NumberValue > 0)
						obj.ForeColor = new SolidColorBrush(Colors.Green);
					else
						obj.ForeColor = new SolidColorBrush(Colors.Red);
				}
				return obj;
			}
			set
			{
				_currentProfit = value;
				NotifyPropertyChanged("CurrentProfit");
			}
		}

		private int _buyPieces = 0;
		public int BuyPieces
		{
			get { return _buyPieces; }
			set
			{
				_buyPieces = value;
				NotifyPropertyChanged("CurrentProfit");
				NotifyPropertyChanged("BuyAmount");
			}
		}

		private int _sellPieces = 0;
		public int SellPieces
		{
			get { return _sellPieces; }
			set
			{
				_sellPieces = value;
				NotifyPropertyChanged("CurrentProfit");
				NotifyPropertyChanged("SellAmount");
			}
		}

		public ValueWithBackground _currentValue;
		public ValueWithBackground CurrentValue
		{
			get { return _currentValue; }
			set
			{
				_currentValue = value;
				if (this.CurrentValue.NumberValue >= this.WakeOnValueGreater.NumberValue)
					this.WakeOnValueGreater.Blink = true;
				if (this.CurrentValue.NumberValue <= this.WakeOnValueLower.NumberValue)
					this.WakeOnValueLower.Blink = true;
				NotifyPropertyChanged("CurrentValue");
				NotifyPropertyChanged("CurrentProfit");
				NotifyPropertyChanged("DiffPrc");
				NotifyPropertyChanged("DiffSellPrc");
			}
		}

		public ValueWithBackground _currentPrc;
		public ValueWithBackground CurrentPrc
		{
			get { return _currentPrc; }
			set
			{
				_currentPrc = value;
				if (this.CurrentPrc.NumberValue >= this.WakeOnPosChange.NumberValue)
					this.WakeOnPosChange.Blink = true;
				if (this.CurrentPrc.NumberValue <= this.WakeOnNegChange.NumberValue)
					this.WakeOnNegChange.Blink = true;
				NotifyPropertyChanged("CurrentPrc");
			}
		}

		public bool Highlight { get; set; }
		public ValueWithBackground WakeOnValueGreater { get; set; }
		public ValueWithBackground WakeOnValueLower { get; set; }
		public ValueWithBackground WakeOnNegChange { get; set; }
		public ValueWithBackground WakeOnPosChange { get; set; }

		public StockParameters(string stockParameters)
		{
			string[] tmp = stockParameters.Split('(');
			StockName = tmp[0].Replace("!", "");
			Highlight = tmp[0].Contains("!");
			WakeOnPosChange = new ValueWithBackground();
			WakeOnValueGreater = new ValueWithBackground();
			WakeOnValueLower = new ValueWithBackground();
			WakeOnNegChange = new ValueWithBackground();
			CurrentValue = new ValueWithBackground();
			CurrentPrc = new ValueWithBackground();
			if (tmp.Length < 2)
				return;
			string[] param = tmp[1].Replace(")", "").Split(';').ToArray();
			decimal d = 0;
			if (param.Length > 0) if (decimal.TryParse(param[0], out d)) WakeOnValueGreater.NumberValue = d;
			if (param.Length > 1) if (decimal.TryParse(param[1], out d)) WakeOnValueLower.NumberValue = d;
			if (param.Length > 2) if (decimal.TryParse(param[2], out d)) WakeOnNegChange.NumberValue = d;
			if (param.Length > 3) if (decimal.TryParse(param[3], out d)) WakeOnPosChange.NumberValue = d;
			if (param.Length > 4) if (decimal.TryParse(param[4], out d)) BuyValue = d;
			if (param.Length > 5) if (decimal.TryParse(param[5], out d)) BuyPieces = (int)d;
			if (param.Length > 6) if (decimal.TryParse(param[6], out d)) SellValue = d;
			if (param.Length > 7) if (decimal.TryParse(param[7], out d)) SellPieces = (int)d;
		}

		public override string ToString()
		{
			StringBuilder sb = new StringBuilder();
			if (Highlight)
				sb.Append("!");
			sb.Append(StockName);
			sb.Append("(");
			if (WakeOnValueGreater.NumberValue.HasValue)
				sb.Append(WakeOnValueGreater.NumberValue.Value.ToString());
			sb.Append(";");
			if (WakeOnValueLower.NumberValue.HasValue)
				sb.Append(WakeOnValueLower.NumberValue.Value.ToString());
			sb.Append(";");
			if (WakeOnNegChange.NumberValue.HasValue)
				sb.Append(WakeOnNegChange.NumberValue.Value.ToString());
			sb.Append(";");
			if (WakeOnPosChange.NumberValue.HasValue)
				sb.Append(WakeOnPosChange.NumberValue.Value.ToString());
			sb.Append(";");
			if (BuyValue != 0)
				sb.Append(BuyValue.ToString());
			sb.Append(";");
			if (BuyPieces != 0)
				sb.Append(BuyPieces.ToString());
			sb.Append(";" + SellValue.ToString());
			sb.Append(";" + SellPieces.ToString());
			sb.Append(")");
			return sb.ToString();
		}

		public void ClearBackgrouns()
		{
			WakeOnNegChange.Blink = false;
			WakeOnPosChange.Blink = false;
			WakeOnValueGreater.Blink = false;
			WakeOnValueLower.Blink = false;
		}

		public event PropertyChangedEventHandler PropertyChanged;

		protected void NotifyPropertyChanged(string propName)
		{
			PropertyChangedEventHandler handler = PropertyChanged;
			if (handler != null)
				handler(this, new PropertyChangedEventArgs(propName));
		}
	}
}
